package test;

import static org.junit.Assert.*;
import hospital.Hospital;

import movement.*;

import org.junit.*;

import unit.*;

import dispatch.DispatchCenter;
import emergency.*;


public class testAmbulance {
	
	DispatchCenter center;
	Ambulance ambu;
	Garage garage;
	

    @Before
    public void setUp() throws Exception {
    	center = new DispatchCenter("DC 1",new Location(45,45,"DC 1 - Location"),new Location(60,60,"GarageLocation"));
    	garage = new Garage(new Location(0,0,"Garage"), center);
    	ambu = new Ambulance("Ambulance one", 0, garage);
    }
    
    @Test
    public void testAssignHospital(){
		Hospital h = new Hospital("Lala", new Location(30,30,"Loc"));
		Emergency e = new Fire(new Location(30,30,"Epla"),Severity.SERIOUS,center,Fire.Size.FACILITY, false,2,2);
		ambu.assignEmergency(e);
		ambu.setCurrentLocation(e.getLocation()); // ambulance moves to emergency
    	ambu.assignHospital(h); // ambulances get's hospital assigned when arriving / completing (at) emergency
    	assertEquals(ambu.getToHospital(), h);
    }
    
    @Test (expected=IllegalArgumentException.class) 
    public void testAssignHospitalNoEmergencyAssigned(){
		// ambu has not got an emergency => can't assign hospital to ambulance
    	ambu.assignHospital(new Hospital("Lala", new Location(30,30,"Loc")));
    }
    
    @Test (expected=IllegalArgumentException.class) 
    public void testAssignHospitalNotAtEmergency(){
		Hospital h = new Hospital("Lala", new Location(30,30,"Loc"));
		Emergency e = new Fire(new Location(30,30,"Epla"),Severity.SERIOUS,center,Fire.Size.FACILITY, false,2,2);
		ambu.assignEmergency(e);
    	ambu.assignHospital(h); 
    }
    
    @SuppressWarnings("unused")
	@Test (expected=IllegalArgumentException.class) 
    public void testCreateAmbulanceNullGarage(){
    	Ambulance am = new Ambulance("am",0,null);
    	
    }

	@SuppressWarnings("unused")
	@Test (expected=IllegalArgumentException.class) 
    public void testCreateAmbulanceNullName(){
    	Ambulance am = new Ambulance(null,0,garage);
    }
	
	@Test
    public void testGettersAndSetters() {
    	Location secondLocation = new Location(60,60,"SecondLocation");
    	assertEquals(ambu.isAssigned(),false);
    	assertTrue(ambu.getCurrentLocation().equals(garage.getLocation()));
    	assertEquals(ambu.getHomeLocation(), garage);
    	assertEquals(ambu.getTargetLocation(), null);
    	assertEquals(ambu.getName(), "Ambulance one");
    	assertEquals(ambu.getSpeed(),10); // minimum speed 10 
    	assertEquals(ambu.getToHospital(), null);
    	
    	Garage garage2 = new Garage(new Location(10,10,"Epla"), new DispatchCenter("DC", new Location(10,10,"Epla"), new Location(12,320,"Epl2a")));
    	ambu.setCurrentLocation(secondLocation);
    	ambu.setHomeLocation(garage2);
    	ambu.setTargetLocation(secondLocation);
    	ambu.setName("Ambulance two");
    	ambu.setSpeed(10);
    	assertTrue(ambu.getCurrentLocation().equals(secondLocation));
    	assertEquals(ambu.getHomeLocation(), garage2);
    	assertEquals(ambu.getTargetLocation(), secondLocation);
    	assertEquals(ambu.getName(), "Ambulance two");
    	assertEquals(ambu.getSpeed(),10);
    }
	
	
	@Test (expected=IllegalAccessException.class)
	public void testRevokeInvalidAmbulance() throws IllegalAccessException{
		Unit u2 = new Ambulance("Ambulance-1", 140, garage);
		Emergency em2 = new TrafficAccident(new Location(200,200,"Boem"), Severity.SERIOUS, center, 1, 1);
		
		u2.setCurrentLocation(em2.getLocation());
		u2.assignEmergency(em2);
		u2.revokeUnit();
	}
	
	@Test (expected=IllegalArgumentException.class) 
    public void testSetInvalidCurrentLocation(){
    	ambu.setCurrentLocation(null);
    }
	
	@Test (expected=IllegalArgumentException.class) 
    public void testSetInvaliHomeLocation(){
    	ambu.setHomeLocation(null);
    }
	
	@Test
    public void testSetNegativeSpeed(){
    	ambu.setSpeed(-20);
    	assertEquals(10, ambu.getSpeed());
    }	
	
	@Test 
	public void testToString(){
		assertEquals("Ambulance-Ambulance one",ambu.toString());
	}
	
	@SuppressWarnings("unused")
	@Test
	public void testUnitOfSameTypeOnEmergency() throws IllegalAccessException{
		PoliceCar pt = new PoliceCar("PC2", 50, garage);
		FireTruck ft = new FireTruck("Test", 90, garage, Fire.Size.FACILITY);
		Ambulance ambu2 = new Ambulance("Testing", 100, garage);
		Location loc = new Location(36,36,"Loc");
		
		Emergency em = new TrafficAccident(loc, Severity.NORMAL, center, 1, 3);
		
		em.assignAllUnits(garage);

		//ambulances don't have to wait for their collegues
		assertTrue(ambu.unitsOfSameTypeOnEmergency());
		
		ambu.setCurrentLocation(em.getLocation());
		
		assertTrue(ambu.unitsOfSameTypeOnEmergency());
		
		ambu2.setCurrentLocation(em.getLocation());

		//ambulances don't have to wait for their collegues
		assertTrue(ambu.unitsOfSameTypeOnEmergency());
	}
	
	@Test (expected=IllegalArgumentException.class)
	public void testUnitOfSameTypeOnEmergencyNoEmergency(){
		ambu.unitsOfSameTypeOnEmergency(); // ambulance doesn't have an emergency yet 
	}
}
